//
//  ShoppingLayer.cpp
//  ATM Killer
//
//  Created by Cloner Team on 9/26/14.
//
//

#include "ShoppingLayer.h"
ShoppingLayer::ShoppingLayer() {
    this->currentAvatarID = CHAR_FINGER;
    this->currentBonusCard = 1;
    this->currentChoosenPage = 0;
    this->isPopUpShow = false;
    this->initialize();
}

ShoppingLayer::~ShoppingLayer() {
    
}

void ShoppingLayer::onEnter() {
    Layer::onEnter();
    this->touchesRegister();
}

void ShoppingLayer::onExit() {
    Layer::onExit();
    this->removeAllChildrenWithCleanup(true);
}

void ShoppingLayer::touchesRegister() {
    auto listener = EventListenerTouchAllAtOnce::create();
    listener->onTouchesBegan = CC_CALLBACK_2(ShoppingLayer::onTouchesBegan, this);
    listener->onTouchesMoved = CC_CALLBACK_2(ShoppingLayer::onTouchesMoved, this);
    listener->onTouchesEnded = CC_CALLBACK_2(ShoppingLayer::onTouchesEnded, this);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
    
}

void ShoppingLayer::onTouchesBegan(const std::vector<Touch *> &touches,cocos2d::Event *event) {
    if(this->gameModel->getGameState() == GS_SHOPPING && this->cardDirection == NUM_CARDS_HALT && isPopUpShow == false){
        for (auto touch : touches) {
            Point point = this->convertTouchToNodeSpace(touch);
            Point shoppingBoardPoint = point - Point(this->shoppingBoard->getPositionX() - this->shoppingBoard->getContentSize().width/2, this->shoppingBoard->getPositionY() - this->shoppingBoard->getContentSize().height/2);
            //check current upgrade ID
            for(int i = 0; i < this->cardArray->count(); i++) {
                Face* cardFace = (Face*) this->cardArray->getObjectAtIndex(i);
                RectBody* cardRect = new RectBody(cardFace->getContentSize().width, cardFace->getContentSize().height);
                cardRect->setPosition(Point(cardFace->getPositionX() + cardContentView->getPositionX(), cardFace->getPositionY() + cardContentView->getPositionY()) + this->cardContentView->getContentOffset());
                if (cardFace->isVisible()==true && Utils::checkPointInRect(cardRect, shoppingBoardPoint)) {
                    this->cardChoice = i;
                }
            }
            //check swipe
            RectBody* cardsRegion = new RectBody(410, 310);
            cardsRegion->setPosition(Point(230,220));
            if (Utils::checkPointInRect(cardsRegion, shoppingBoardPoint)) {
                this->swipe = true;
                this->timeOfSwipe = 0.0f;
                this->pointSwipe = point;
            }
            //check avatars
            __Array* allKeys = this->avatars->allKeys();
            for (int i = 0; i < allKeys->count(); i++) {
                __Integer* key = (__Integer*) allKeys->getObjectAtIndex(i);
                Face* holder = (Face*)this->avatars->objectForKey(key->getValue());
                RectBody* holderRect = new RectBody(holder->getContentSize().width, holder->getContentSize().height);
                holderRect->setPosition(holder->getPosition());
                if (Utils::checkPointInRect(holderRect, point)) {
                    this->currentAvatarID = key->getValue();
                    this->notify(REQ_CHANGE_AVATAR_SHOPPING, EVT_CLICK_BUTTON, NULL, 0, NULL);
                }
            }
        }
    }
    
}

void ShoppingLayer::onTouchesMoved(const std::vector<Touch *> &touches, cocos2d::Event *event) {
    this->cardChoice = -1 ;
}

void ShoppingLayer::onTouchesEnded(const std::vector<Touch *> &touches, cocos2d::Event *event){
    if(this->gameModel->getGameState() == GS_SHOPPING && this->cardDirection == NUM_CARDS_HALT && this->isPopUpShow == false){
        for (auto touch : touches) {
            Point point = this->convertTouchToNodeSpace(touch);
            Point shoppingBoardPoint = point - Point(this->shoppingBoard->getPositionX() - this->shoppingBoard->getContentSize().width/2, this->shoppingBoard->getPositionY() - this->shoppingBoard->getContentSize().height/2);
            //check swipe
            RectBody* cardsRegion = new RectBody(410, 310);
            cardsRegion->setPosition(Point(230,220));
            float distance = Utils::distance(point, this->pointSwipe);
            float speed = distance / this->timeOfSwipe;
            if (this->swipe == true ) {
                if (speed > 150 && distance > 70) { // change page
                    if (point.x > this->pointSwipe.x){
                        if (this->currentChoosenPage > 0) {
                            this->currentChoosenPage -- ;
                            this->finishContentOffset = this->currentChoosenPage * (-392);
                            this->contentOffsetSpeed = 98;
                            this->cardDirection = NUM_CARDS_RIGHT;
                        }
                    }
                    if (point.x < this->pointSwipe.x){
                        if (this->currentChoosenPage < this->pageButtons->count() - 1) {
                            this->currentChoosenPage ++;
                            this->finishContentOffset = this->currentChoosenPage * (-392);
                            this->contentOffsetSpeed = -98;
                            this->cardDirection = NUM_CARDS_LEFT;
                        }
                    }
                }
            }
            
            //card choice
            for(int i = 0; i < this->cardArray->count(); i++) {
                Face* cardFace = (Face*) this->cardArray->getObjectAtIndex(i);
                RectBody* cardRect = new RectBody(cardFace->getContentSize().width, cardFace->getContentSize().height);
                cardRect->setPosition(Point(cardFace->getPositionX() + cardContentView->getPositionX(), cardFace->getPositionY() + cardContentView->getPositionY()) + this->cardContentView->getContentOffset());
                if (cardFace->isVisible()==true && Utils::checkPointInRect(cardRect, shoppingBoardPoint)) {
                    if (this->cardChoice == i) {
                        this->currentBonusCard = cardFace->getTag();
                    }
                }
            }
            this->swipe = false;
            this->cardChoice = -1;
        }
    }
}

void ShoppingLayer::onButtonClick(Ref* sender) {
    //continue
    if(sender == this->getContinueButton()){
        this->notify(REQ_RESUME, EVT_CLICK_BUTTON, NULL, 0, NULL);
    }
    if(sender == this->getOkButton())
    {
        //special upgrade
        if (this->getOkButton()->getTag() == 2) {
            int avatarId = this->currentAvatarID;
            if( avatarId == CHAR_FINGER){
                this->notify(REQ_UPGRADE_BONUS_FINGER, EVT_CLICK_BUTTON, NULL, 0, NULL);
            } else if(avatarId == CHAR_ATM){
                this->notify(REQ_UPGRADE_BONUS_ATM, EVT_CLICK_BUTTON, NULL, 0, NULL);
            }
            this->cancelPopUp(sender);
        }
    }
}

void ShoppingLayer::onChangeAvatar(Ref* data) {
    //remove old cards
    for(int i = 0; i < this->cardArray->count(); i++) {
        Face* card = (Face*) this->cardArray->getObjectAtIndex(i);
        card->removeFromParentAndCleanup(true);
    }
    this->cardArray->removeAllObjects();
    //create new cards
    this->createCards();
    this->arrangeCards();
    //remove old page buttons
    for(int i = 0; i < this->pageButtons->count(); i++) {
        Face* pageButton = (Face*) this->pageButtons->getObjectAtIndex(i);
        pageButton->removeFromParentAndCleanup(true);
    }
    this->pageButtons->removeAllObjects();
    //calculate number of page buttons
    this->createPageButtons();
    this->currentChoosenPage = 0;
    this->currentBonusCard = 1;
    this->cardContentView->setContentOffset(Point(0,0));
}

void ShoppingLayer::onShowBonusNoti(Ref* data){
    __Integer* idInteger = (__Integer*)data;
    __Array* allKeys = this->avatars->allKeys();
    for(int i = 0; i < allKeys->count(); i++) {
        __Integer* key = (__Integer*) allKeys->getObjectAtIndex(i);
        if (key->getValue() == idInteger->getValue()){
            Face* avatar = (Face*)this->avatars->objectForKey(key->getValue());
            Face* notiFace = (Face*) avatar->getChildByTag(1);
            notiFace->setVisible(true);
        }
    }
}

void ShoppingLayer::onRemoveBonusNoti(Ref* data){
    __Integer* idInteger = (__Integer*)data;
    __Array* allKeys = this->avatars->allKeys();
    for(int i = 0; i < allKeys->count(); i++) {
        __Integer* key = (__Integer*) allKeys->getObjectAtIndex(i);
        if (key->getValue() == idInteger->getValue()){
            Face* avatar = (Face*)this->avatars->objectForKey(key->getValue());
            Face* notiFace = (Face*) avatar->getChildByTag(1);
            notiFace->setVisible(false);
        }
    }
}

void ShoppingLayer::initialize() {
    this->cardArray = __Array::create();
    CC_SAFE_RETAIN(this->cardArray);
    this->pageButtons = __Array::create();
    CC_SAFE_RETAIN(this->pageButtons);
    this->avatars = __Dictionary::create();
    CC_SAFE_RETAIN(this->avatars);
    this->boardLayer = 0;
    this->gameModel = GameModel::getInstance();
    
    this->shoppingListener = ShoppingListener::create();
    this->shoppingListener->setHandlerObj(this);
    this->shoppingListener->setChangeCharacter(ug_listener_func(ShoppingLayer::onChangeAvatar));
    this->gameModel->addListener(this->shoppingListener);
    
    this->notificationListener = NotificationListener::create();
    this->notificationListener->setHandlerObj(this);
    this->notificationListener->setShowBonusNotification(ug_listener_func(ShoppingLayer::onShowBonusNoti));
    this->notificationListener->setRemoveBonusNotification(ug_listener_func(ShoppingLayer::onRemoveBonusNoti));
    this->gameModel->addListener(this->notificationListener);
    
    this->createLayers();
    this->createLayersContent();
}

void ShoppingLayer::createLayers() {
    this->grayLayer = UGLayerColor::create();
    this->grayLayer->initWithColor(Color4B(0,0,0,100));
    this->addChild(this->grayLayer);
    
    this->boardLayer = UGLayer::create();
    this->addChild(this->boardLayer);
    
    this->popUpLayer = UGLayer::create();
    this->addChild(this->popUpLayer);
    
    this->avatarLayer = UGLayer::create();
    this->addChild(this->avatarLayer);
    
    this->cardLayer = UGLayer::create();
}

void ShoppingLayer::createLayersContent() {
    this->loadShoppingBoard();
    this->loadPopUp();
    this->loadAvatar();
}

void ShoppingLayer::loadShoppingBoard() {
    Size gameSize = this->gameModel->getDisplayResolutionSize();
    //shopping board
    this->shoppingBoard = new Face();
    this->shoppingBoard->initWithSpriteFrameName((char*)ANI_BOARD_GUI);
    this->shoppingBoard->setPosition(gameSize.width/2 + 30, gameSize.height/2);
    this->boardLayer->addChild(this->shoppingBoard);
    
    //character title
    Label* boardTitle = Utils::createLabel((char*)"Bonus Upgrade", (char*)FONT_TRANSFORMER, 32);
    boardTitle->setPosition(this->shoppingBoard->getContentSize().width/2 - 130,this->shoppingBoard->getContentSize().height - 35);
    this->shoppingBoard->addChild(boardTitle);
    
    //money bar
    Face* moneyBar = new Face();
    moneyBar->initWithSpriteFrameName(ANI_MONEY_BAR);
    moneyBar->setPosition(this->shoppingBoard->getContentSize().width - moneyBar->getContentSize().width/2 - 25, this->shoppingBoard->getContentSize().height - 30);
    this->shoppingBoard->addChild(moneyBar);
    
    this->currentMoneyLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 28);
    this->currentMoneyLabel->setDimensions(300, this->currentMoneyLabel->getDimensions().height);
    this->currentMoneyLabel->setPosition(moneyBar->getContentSize().width/2 - 30, moneyBar->getContentSize().height/2 - 3);
    moneyBar->addChild(this->currentMoneyLabel);
    
    UGMenu* buttonMenu = UGMenu::create();
    buttonMenu->setPosition(Point::ZERO);
    this->shoppingBoard->addChild(buttonMenu);
    //purchase button
    this->purchaseButton = Utils::createButton((char*)ANI_BUTTON_PURCHASE_1, (char*) ANI_BUTTON_PURCHASE_2);
    this->purchaseButton->setPosition(655,140);
    buttonMenu->addChild(this->purchaseButton);
    this->purchaseButton->setCallback(CC_CALLBACK_1(ShoppingLayer::showBonusPopUp,this));
    
    //continue button
    this->continueButton = Utils::createButton((char*)ANI_BUTTON_CONTINUE_1, (char*)ANI_BUTTON_CONTINUE_2);
    this->continueButton->setPosition(655,67);
    buttonMenu->addChild(this->continueButton);
    this->continueButton->setCallback(CC_CALLBACK_1(ShoppingLayer::onButtonClick,this));
    
    //character
    //name
    this->nameLabel = Utils::createLabel((char*)"INCREDIBLE FINGER", (char*)FONT_TRANSFORMER, 32);
    this->nameLabel->setAnchorPoint(Point(0,0.5));
    this->nameLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->nameLabel->setPosition(Point(50, 535));
    this->nameLabel->setDimensions(400, this->nameLabel->getContentSize().height);
    this->shoppingBoard->addChild(nameLabel);
    //mps
    this->mpsLabel = Utils::createLabel((char*)"Money per touch: $1", (char*)FONT_MYRIADPRO_BOLD , 18);
    this->mpsLabel->setAnchorPoint(Point(0,0.5));
    this->mpsLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->mpsLabel->setColor(Color3B(128,215,255));
    this->mpsLabel->setPosition(Point(50,507));
    this->mpsLabel->setDimensions(400, this->mpsLabel->getContentSize().height);
    this->shoppingBoard->addChild(this->mpsLabel);
    
    //upgrade info
    //upgrade name
    this->upgradeNameLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 30);
    this->upgradeNameLabel->setDimensions(350, this->upgradeNameLabel->getDimensions().height);
    this->upgradeNameLabel->setAnchorPoint(Point(0,1));
    this->upgradeNameLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->upgradeNameLabel->setColor(Color3B(128, 215, 255));
    this->upgradeNameLabel->setPosition(490, 362);
    this->shoppingBoard->addChild(this->upgradeNameLabel);
    //upgrade effect
    this->upgradeEffectLabel = Utils::createLabel((char*)"0", (char*)FONT_MYRIADPRO_BOLD, 20);
    this->upgradeEffectLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->upgradeEffectLabel->setAnchorPoint(Point(0, 1));
    this->upgradeEffectLabel->setPosition(490, 330);
    this->upgradeEffectLabel->setDimensions(340, this->upgradeEffectLabel->getContentSize().height);
    this->shoppingBoard->addChild(this->upgradeEffectLabel);
    
    //upgrade required Label
    this->requiredMoneyLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 23);
    this->requiredMoneyLabel->setAnchorPoint(Point(0,1));
    this->requiredMoneyLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->requiredMoneyLabel->setColor(Color3B(255,174,7));
    this->requiredMoneyLabel->setPosition(490,330);
    this->requiredMoneyLabel->setDimensions(340, 70);
    this->shoppingBoard->addChild(this->requiredMoneyLabel);
    
    //upgrade desc
    this->upgradeDescLabel = Utils::createLabel((char*)"0", (char*)FONT_MYRIADPRO_BOLDIT, 20);
    this->upgradeDescLabel->setAnchorPoint(Point(0, 1));
    this->upgradeDescLabel->setPosition(487, 300);
    this->upgradeDescLabel->setDimensions(330,110);
    this->upgradeDescLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    this->shoppingBoard->addChild(this->upgradeDescLabel);
    
    //upgrade cost
    this->upgradeCostLabel = Utils::createLabel((char*)"$ 0",(char*)FONT_TRANSFORMER, 28);
    this->upgradeCostLabel->setAnchorPoint(Point(1,0));
    this->upgradeCostLabel->setColor(Color3B(255,174,7));
    this->upgradeCostLabel->setPosition(810,175);
    this->upgradeCostLabel->setDimensions(300, this->upgradeCostLabel->getContentSize().height);
    this->upgradeCostLabel->setHorizontalAlignment(TextHAlignment::RIGHT);
    this->shoppingBoard->addChild(this->upgradeCostLabel);
    
    //cards
    this->createCards();
    this->arrangeCards();
    this->cardContentView = ScrollView::create(Size(380, 400));
    this->cardContentView->setPosition(40, 0);
    this->cardContentView->setContainer(this->cardLayer);
    this->cardContentView->setDirection(ScrollView::Direction::HORIZONTAL);
    this->cardContentView->setContentOffset(Point(0,0));
    this->cardContentView->setTouchEnabled(false);
    this->shoppingBoard->addChild(this->cardContentView);
    //page buttons
    this->createPageButtons();
    
}

void ShoppingLayer::loadAvatar() {
    //finger
    {
        FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
        Face* holder = new Face();
        holder->initWithSpriteFrameName((char*)ANI_AVATAR_HOLDER_2);
        holder->setPosition(this->shoppingBoard->getPositionX() - this->shoppingBoard->getContentSize().width/2 - 40, this->shoppingBoard->getPositionY() + this->shoppingBoard->getContentSize().height/2 - 100);
        holder->setTag(CHAR_FINGER);
        
        Face* fingerAvatar = new Face();
        fingerAvatar->initWithSpriteFrameName(fingerInfo->getAvatarImage());
        fingerAvatar->setPosition(holder->getContentSize().width/2 - 4, holder->getContentSize().height/2+1);
        holder->addChild(fingerAvatar, 10);
        fingerAvatar->setTag(0);
        
        Face* notiFace = new Face();
        notiFace->initWithSpriteFrameName(ANI_NOTI);
        notiFace->setPosition(holder->getContentSize().width - notiFace->getContentSize().width/2, holder->getContentSize().height - notiFace->getContentSize().height/2);
        holder->addChild(notiFace,11);
        notiFace->setTag(1);
        notiFace->setVisible(false);
        
        this->avatarLayer->addChild(holder);
        this->avatars->setObject(holder, CHAR_FINGER);
    }
    //atm
    {
        AtmInformation* atmInfo = this->gameModel->getAtmInformation();
        Face* holder = new Face();
        holder->initWithSpriteFrameName((char*)ANI_AVATAR_HOLDER_2);
        holder->setPosition(this->shoppingBoard->getPositionX() - this->shoppingBoard->getContentSize().width/2 - 40, this->shoppingBoard->getPositionY() + this->shoppingBoard->getContentSize().height/2 - 175);
        holder->setTag(CHAR_ATM);
        
        Face* atmAvatar = new Face();
        atmAvatar->initWithSpriteFrameName(atmInfo->getAvatarImage());
        atmAvatar->setPosition(holder->getContentSize().width/2 - 4, holder->getContentSize().height/2+1);
        holder->addChild(atmAvatar, 10);
        atmAvatar->setTag(0);
        
        Face* notiFace = new Face();
        notiFace->initWithSpriteFrameName(ANI_NOTI);
        notiFace->setPosition(holder->getContentSize().width - notiFace->getContentSize().width/2, holder->getContentSize().height - notiFace->getContentSize().height/2);
        holder->addChild(notiFace,11);
        notiFace->setTag(1);
        notiFace->setVisible(false);
        
        this->avatarLayer->addChild(holder);
        this->avatars->setObject(holder, CHAR_ATM);
    }
    
}

void ShoppingLayer::loadPopUp(){
    Size gameSize = this->gameModel->getDisplayResolutionSize();
    this->popUpFace = new Face();
    this->popUpFace->initWithSpriteFrameName(ANI_POP_UP_BG);
    this->popUpFace->setPosition(gameSize.width/2, gameSize.height/2);
    this->popUpLayer->addChild(this->popUpFace);
    
    Label* labelPopUp1 = Utils::createLabel((char*)"Are you sure to spend", (char*)FONT_TRANSFORMER, 28);
    labelPopUp1->setColor(Color3B(255,255,255));
    labelPopUp1->setAnchorPoint(Point(0.5,1));
    labelPopUp1->setDimensions(350, 100);
    labelPopUp1->setPosition(this->popUpFace->getContentSize().width/2, 215);
    labelPopUp1->setTag(1);
    
    Label* labelPopUp2 = Utils::createLabel((char*)"$123.456 Million", (char*)FONT_TRANSFORMER,35);
    labelPopUp2->setColor(Color3B(255,174,7));
    labelPopUp2->setPosition(this->popUpFace->getContentSize().width/2, 150);
    labelPopUp2->setTag(2);
    
    Label* labelPopUp3 = Utils::createLabel((char*)"Kid gain 34 Dps this upgrade level up to 124",(char*)FONT_MYRIADPRO_REGULAR, 17);
    labelPopUp3->setDimensions(labelPopUp1->getDimensions().width - 30, 200);
    labelPopUp3->setColor(Color3B(255,255,255));
    labelPopUp3->setAnchorPoint(Point(0.5,1));
    labelPopUp3->setPosition(this->popUpFace->getContentSize().width/2, 122);
    labelPopUp3->setTag(3);
    
    this->popUpFace->addChild(labelPopUp1);
    this->popUpFace->addChild(labelPopUp2);
    this->popUpFace->addChild(labelPopUp3);
    
    UGMenu* popUpMenu = UGMenu::create();
    popUpMenu->setPosition(Point::ZERO);
    // OK Button and Cancel button
    this->okButton = Utils::createButton((char*)ANI_BUTTON_OK_1, (char*)ANI_BUTTON_OK_2);
    this->okButton->setPosition(125,50);
    this->cancelButton = Utils::createButton((char*)ANI_BUTTON_CANCEL_1, (char*)ANI_BUTTON_CANCEL_2);
    cancelButton->setPosition(275,50);
    popUpMenu->addChild(this->okButton);
    popUpMenu->addChild(this->cancelButton);
    this->cancelButton->setCallback(CC_CALLBACK_1(ShoppingLayer::cancelPopUp,this));
    this->popUpFace->addChild(popUpMenu);
    this->popUpFace->setVisible(false);
}

void ShoppingLayer::cancelPopUp(Ref *sender) {
    this->isPopUpShow = false;
    this->popUpFace->setVisible(false);
}

void ShoppingLayer::showBonusPopUp(Ref *sender) {
    BigNumber* tempPrice;
    string tempEffect;
    string tempName;
    int nextUpgradeLevel;
    if (this->currentAvatarID == CHAR_FINGER) {
        Finger* finger = this->gameModel->getFinger();
        FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
        FingerBonus* fingerBonus = (FingerBonus*) fingerInfo->getBonusInfo()->getObjectAtIndex(this->currentBonusCard - 1);
        tempPrice = fingerBonus->getPrice();
        tempEffect = fingerBonus->getEffect();
        tempName = "Finger";
        nextUpgradeLevel = finger->getBonusLevel() + 1;
    }
    
    if (this->currentAvatarID == CHAR_ATM) {
        Atm* atm = this->gameModel->getAtm();
        AtmInformation* atmInfo = this->gameModel->getAtmInformation();
        AtmBonus* atmBonus = (AtmBonus*) atmInfo->getBonusInfo()->getObjectAtIndex(this->currentBonusCard);
        tempPrice = atmBonus->getPrice();
        tempEffect = atmBonus->getEffect();
        tempName = "Atm";
        nextUpgradeLevel = atm->getBonusLevel() + 1;
    }
    if(gameModel->getScore()->compare(tempPrice)>=0)
    {
        // set label
        char labelPopUp1Text[200];
        sprintf(labelPopUp1Text, TXT_SURE_LEVEL_UP);
        Label* labelPopUp1 = (Label*) this->popUpFace->getChildByTag(1);
        labelPopUp1->setString(labelPopUp1Text);
        labelPopUp1->setPosition(this->popUpFace->getContentSize().width/2, 205);
        
        char labelPopUp2Text[200];
        char* costUpgrade = tempPrice->display();
        sprintf(labelPopUp2Text,TXT_MONEY_FORMAT, costUpgrade);
        delete[]costUpgrade;
        Label* labelPopUp2 = (Label*)this->popUpFace->getChildByTag(2);
        labelPopUp2->setPosition(this->popUpFace->getContentSize().width/2, 150);
        labelPopUp2->setString(labelPopUp2Text);
        
        char labelPopUp3Text[200];
        sprintf(labelPopUp3Text,"%s", tempEffect.c_str());
        Label* labelPopUp3 = (Label*)this->popUpFace->getChildByTag(3);
        labelPopUp3->setString(labelPopUp3Text);
        labelPopUp3->setVisible(true);
        
        this->getCancelButton()->setVisible(true);
        this->getOkButton()->setPosition(125,50);
    } else {
        char labelPopUp1Text[200];
        sprintf(labelPopUp1Text, TXT_NOT_ENOUGH_MONEY);
        Label* labelPopUp1 = (Label*) this->popUpFace->getChildByTag(1);
        labelPopUp1->setString(labelPopUp1Text);
        labelPopUp1->setPosition(this->popUpFace->getContentSize().width/2, 215);
        
        char labelPopUp2Text[200];
        char* costCharacter = tempPrice->display();
        sprintf(labelPopUp2Text,TXT_MONEY_FORMAT, costCharacter);
        delete[] costCharacter;
        Label* labelPopUp2 = (Label*)this->popUpFace->getChildByTag(2);
        labelPopUp2->setString(labelPopUp2Text);
        labelPopUp2->setPosition(this->popUpFace->getContentSize().width/2, 110);
        
        Label* labelPopUp3 = (Label*)this->popUpFace->getChildByTag(3);
        labelPopUp3->setVisible(false);
        
        this->getOkButton()->setPosition(200,50);
        this->getCancelButton()->setVisible(false);
        
    }
    // set callback
    this->getOkButton()->setCallback(CC_CALLBACK_1(ShoppingLayer::onButtonClick,this));
    this->getOkButton()->setTag(2);
    
    this->popUpFace->setVisible(true);
    this->isPopUpShow = true;
}

void ShoppingLayer::createCards() {
    if (this->currentAvatarID == CHAR_FINGER) {
        Finger* finger = this->gameModel->getFinger();
        FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
        for (int i = 0; i < fingerInfo->getBonusInfo()->count(); i++) {
            FingerBonus* fingerBonus = (FingerBonus*) fingerInfo->getBonusInfo()->getObjectAtIndex(i);
            Face* bonusCard = new Face();
            bonusCard->initWithSpriteFrameName((char*)ANI_CARD_1);
            bonusCard->setTag(fingerBonus->getBonusId());//bonus level is set in tag
            
            //upgrade avatar
            Face* bonusAvatar = new Face();
            bonusAvatar->initWithSpriteFrameName(fingerBonus->getBonusAvatar());
            bonusAvatar->setPosition(Point(bonusCard->getContentSize().width/2 + 1,bonusCard->getContentSize().height/2 + 15));
            bonusCard->addChild(bonusAvatar);
            bonusAvatar->setTag(1);
            
            //status
            Face* statusCard = new Face();
            statusCard->setPosition(bonusCard->getContentSize().width/2, 10);
            if (fingerBonus->getBonusId()<=finger->getBonusLevel()) {
                statusCard->initWithSpriteFrameName((char*)ANI_TAG_PURCHASE);
            } else {
                statusCard->initWithSpriteFrameName((char*)ANI_TAG_LOCKED);
            }
            statusCard->setTag(0);
            bonusCard->addChild(statusCard);
            //noti
            Face* notiFace = new Face();
            notiFace->initWithSpriteFrameName(ANI_NOTI);
            notiFace->setPosition(bonusCard->getContentSize().width - notiFace->getContentSize().width/2, bonusCard->getContentSize().height);
            bonusCard->addChild(notiFace,11);
            FiniteTimeAction* fadeInAction = FadeTo::create(0.5f,255);
            FiniteTimeAction* fadeOutAction = FadeTo::create(0.5f,100);
            ActionInterval* sequenceAction = Sequence::create(fadeOutAction, fadeInAction, NULL);
            RepeatForever* repeatAction = RepeatForever::create(sequenceAction);
            notiFace->runAction(repeatAction);
            notiFace->setTag(2);
            notiFace->setVisible(false);
            
            this->cardLayer->addChild(bonusCard);
            this->cardArray->addObject(bonusCard);
        }
    }
    if (this->currentAvatarID == CHAR_ATM) {
        Atm* atm = this->gameModel->getAtm();
        AtmInformation* atmInfo = this->gameModel->getAtmInformation();
        for ( int i = 1; i < atmInfo->getBonusInfo()->count(); i++) {
            AtmBonus* atmBonus = (AtmBonus*) atmInfo->getBonusInfo()->getObjectAtIndex(i);
            Face* bonusCard = new Face();
            bonusCard->initWithSpriteFrameName((char*)ANI_CARD_1);
            bonusCard->setTag(atmBonus->getBonusId());//bonus level is set in tag
            
            //upgrade avatar
            Face* bonusAvatar = new Face();
            bonusAvatar->initWithSpriteFrameName(atmBonus->getBonusAvatar());
            bonusAvatar->setPosition(Point(bonusCard->getContentSize().width/2 + 1, bonusCard->getContentSize().height/2 + 15));
            bonusCard->addChild(bonusAvatar);
            bonusAvatar->setTag(1);
            
            //status
            Face* statusCard = new Face();
            statusCard->setPosition(bonusCard->getContentSize().width/2, 10);
            if (atmBonus->getBonusId()<=atm->getBonusLevel()) {
                statusCard->initWithSpriteFrameName((char*)ANI_TAG_PURCHASE);
            } else {
                statusCard->initWithSpriteFrameName((char*)ANI_TAG_LOCKED);
            }
            statusCard->setTag(0);
            bonusCard->addChild(statusCard);
            //noti
            Face* notiFace = new Face();
            notiFace->initWithSpriteFrameName(ANI_NOTI);
            notiFace->setPosition(bonusCard->getContentSize().width - notiFace->getContentSize().width/2, bonusCard->getContentSize().height);
            bonusCard->addChild(notiFace,11);
            FiniteTimeAction* fadeInAction = FadeTo::create(0.5f,255);
            FiniteTimeAction* fadeOutAction = FadeTo::create(0.5f,100);
            ActionInterval* sequenceAction = Sequence::create(fadeOutAction, fadeInAction, NULL);
            RepeatForever* repeatAction = RepeatForever::create(sequenceAction);
            notiFace->runAction(repeatAction);
            notiFace->setTag(2);
            notiFace->setVisible(false);
            
            this->cardLayer->addChild(bonusCard);
            this->cardArray->addObject(bonusCard);
        }
    }
}


void ShoppingLayer::arrangeCards() {
    for (int i = 0; i < this->cardArray->count(); i++){
        Face* upgradeCard = (Face*)this->cardArray->getObjectAtIndex(i);
        int page = i / 6;
        int index = i % 6 ;
        int startWidth = 60 + 390 * page;
        int width = startWidth + (index % 3) * 130;
        int height = 300 - (160 * (int)(index / 3));
        upgradeCard->setPosition(width, height);
    }
    
}

void ShoppingLayer::createPageButtons() {
    if(this->currentAvatarID == CHAR_FINGER) {
        FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
        int numberOfPage = (int)(fingerInfo->getBonusInfo()->count()/6);
        if ((fingerInfo->getBonusInfo()->count())%6 != 0) {
            numberOfPage +=1;
        }
        for (int i = 0; i < numberOfPage; i++) {
            Face* pageFace = new Face();
            pageFace->initWithSpriteFrameName(ANI_PAGE_CHOSE_2);
            this->shoppingBoard->addChild(pageFace);
            pageFace->setPosition(230 - (numberOfPage-1) * 20 + i * 40, 40);
            this->pageButtons->addObject(pageFace);
        }
    }
    if(this->currentAvatarID == CHAR_ATM) {
        AtmInformation* atmInfo = this->gameModel->getAtmInformation();
        int numberOfPage = (int)(atmInfo->getBonusInfo()->count()/6);
        if ((atmInfo->getBonusInfo()->count())%6 != 0) {
            numberOfPage +=1;
        }
        for (int i = 0; i < numberOfPage; i++) {
            Face* pageFace = new Face();
            pageFace->initWithSpriteFrameName(ANI_PAGE_CHOSE_2);
            this->shoppingBoard->addChild(pageFace);
            pageFace->setPosition(230 - (numberOfPage-1) * 20 + i * 40, 40);
            this->pageButtons->addObject(pageFace);
        }
    }
}

void ShoppingLayer::update(float dt) {
    if(gameModel->getGameState() == GS_SHOPPING)
    {
        this->grayLayer->setVisible(true);
        this->boardLayer->setVisible(true);
        this->avatarLayer->setVisible(true);
    }
    else
    {
        this->grayLayer->setVisible(false);
        this->boardLayer->setVisible(false);
        this->avatarLayer->setVisible(false);
    }
    //calculate time of swipe
    if (swipe == true) {
        this->timeOfSwipe += dt;
    }
    //contentOffsetCards
    if (this->cardDirection == NUM_CARDS_RIGHT)
    {
        if (this->cardContentView->getContentOffset().x <= this->finishContentOffset - 1) {
            this->cardContentView->setContentOffset(this->cardContentView->getContentOffset() + Point(contentOffsetSpeed, 0));
        } else {
            this->cardContentView->setContentOffset(Point(this->finishContentOffset,0));
            this->cardDirection = NUM_CARDS_HALT;
        }
        
    } else if (this->cardDirection == NUM_CARDS_LEFT) {
        if (this->cardContentView->getContentOffset().x >= this->finishContentOffset + 1) {
            this->cardContentView->setContentOffset(this->cardContentView->getContentOffset() + Point(contentOffsetSpeed, 0));
        } else {
            this->cardContentView->setContentOffset(Point(this->finishContentOffset,0));
            this->cardDirection = NUM_CARDS_HALT;
        }
    }
    
    //update page and update arcording cards
    {
        for (int i = 0; i < this->pageButtons->count(); i++) {
            Face* pageFace = (Face*) this->pageButtons->getObjectAtIndex(i);
            pageFace->setSpriteFrame(ANI_PAGE_CHOSE_2);
        }
        Face* pageFace = (Face*)this->pageButtons->getObjectAtIndex(this->currentChoosenPage);
        pageFace->setSpriteFrame(ANI_PAGE_CHOSE_1);
    }
    //update selected avatar
    {
        __Array* allKeys = this->avatars->allKeys();
        for (int i = 0; i < allKeys->count(); i++) {
            __Integer* key = (__Integer*) allKeys->getObjectAtIndex(i);
            Face* holder = (Face*)this->avatars->objectForKey(key->getValue());
            if (key->getValue() == this->currentAvatarID) {
                holder->setSpriteFrame(ANI_AVATAR_HOLDER_1);
            } else {
                holder->setSpriteFrame(ANI_AVATAR_HOLDER_2);
            }
        }
    }
    //update status of cards
    {
        int bonusLevel;
        bool hasNoti;
        if (this->currentAvatarID == CHAR_FINGER) {
            Finger* finger = this->gameModel->getFinger();
            bonusLevel = finger->getBonusLevel();
            hasNoti = finger->getHasNotiBonus();
        } else if (this->currentAvatarID == CHAR_ATM) {
            Atm* atm = this->gameModel->getAtm();
            bonusLevel = atm->getBonusLevel();
            hasNoti = atm->getHasNotiBonus();
        }
        for (int i = 0; i < this->cardArray->count(); i++) {
            Face* card = (Face*)this->cardArray->getObjectAtIndex(i);
            int levelBonusOfCard = card->getTag();
            //selected
            if (levelBonusOfCard == this->currentBonusCard ) {
                card->setSpriteFrame(ANI_CARD_2);
            } else {
                card->setSpriteFrame(ANI_CARD_1);
            }
            //noti
            Face* notiFace = (Face*) card->getChildByTag(2);
            //status
            Face* status = (Face*) card->getChildByTag(0);
            if (levelBonusOfCard <= bonusLevel) {
                status->setSpriteFrame((char*)ANI_TAG_PURCHASE);
                status->setUserData((char*)"purchased");
            } else if(levelBonusOfCard == bonusLevel+ 1){
                if (this->currentAvatarID == CHAR_FINGER){
                    Finger* finger = this->gameModel->getFinger();
                    if(finger->getBonusAvailable() == true) {
                        status->setSpriteFrame((char*)ANI_TAG_AVAILABLE);
                        status->setUserData((char*)"available");
                        if(finger->getHasNotiBonus() == true){
                            notiFace->setVisible(true);
                        } else {
                            notiFace->setVisible(false);
                        }
                    } else {
                        status->setSpriteFrame((char*)ANI_TAG_LOCKED);
                        status->setUserData((char*)"locked");
                    }
                } else if (this->currentAvatarID == CHAR_ATM) {
                    Atm* atm = this->gameModel->getAtm();
                    if(atm->getBonusAvailable() == true) {
                        status->setSpriteFrame((char*)ANI_TAG_AVAILABLE);
                        status->setUserData((char*)"available");
                        if(atm->getHasNotiBonus() == true){
                            notiFace->setVisible(true);
                        } else {
                            notiFace->setVisible(false);
                        }
                    } else {
                        status->setSpriteFrame((char*)ANI_TAG_LOCKED);
                        status->setUserData((char*)"locked");
                    }
                }
            } else {
                status->setSpriteFrame((char*)ANI_TAG_LOCKED);
                status->setUserData((char*)"locked");
            }
            //bonusAvatar
            Face* bonusAvatar = (Face*)card->getChildByTag(1);
            if (levelBonusOfCard > bonusLevel) {
                bonusAvatar->setVisible(false);
            } else {
                bonusAvatar->setVisible(true);
            }
        }
        if(hasNoti == true) {
            if (this->currentBonusCard == bonusLevel + 1) {
                this->notify(REQ_REMOVE_BONUS_NOTIFICATION, EVT_DEFAULT, NULL, 0, __Integer::create(this->currentAvatarID));
            }
        }
    }
    
    //update status of purchase button
    {
        Face* card = (Face*)this->cardArray->getObjectAtIndex(this->currentBonusCard -1);
        Face* status = (Face*)card->getChildByTag(0);
        char* state = (char*)status->getUserData();
        if (strcmp(state, "locked") == 0 || strcmp(state,"purchased") == 0) {
            this->purchaseButton->setVisible(false);
            this->upgradeCostLabel->setVisible(false);
        } else if (strcmp(state,"available") == 0) {
            this->purchaseButton->setVisible(true);
            this->upgradeCostLabel->setVisible(true);
        }
        
    }
    //update information
    {
        Face* card = (Face*)this->cardArray->getObjectAtIndex(this->currentBonusCard - 1);
        Face* status = (Face*) card->getChildByTag(0);
        char* currentStatus = (char*) status->getUserData();
        //current money
        char money[100];
        char* moneyText = this->gameModel->getScore()->display();
        sprintf(money,"$ %s", moneyText);
        delete[] moneyText;
        this->currentMoneyLabel->setString(money);
        this->currentMoneyLabel->setPosition(143, 26);
        
        char* nameText;
        char* mpcText;
        char upgradeNameText[200];
        char upgradeEffectText[200];
        char upgradeDescText[200];
        char* requiredMoneyText;
        char* costUpgradeText;
        if(this->currentAvatarID == CHAR_FINGER) {
            FingerInformation* fingerInfo = this->gameModel->getFingerInformation();
            FingerBonus* fingerBonus = (FingerBonus*) fingerInfo->getBonusInfo()->getObjectAtIndex(this->currentBonusCard - 1);
            nameText = (char*)"Finger";
            mpcText = (char*)this->gameModel->getCounter()->getMoneyPerTouch()->display();
            sprintf(upgradeNameText, "%s", fingerBonus->getName().c_str());
            sprintf(upgradeEffectText, "%s", fingerBonus->getEffect().c_str());
            sprintf(upgradeDescText, "%s", fingerBonus->getDescription().c_str());
            requiredMoneyText = fingerBonus->getCondition()->display();
            costUpgradeText = fingerBonus->getPrice()->display();
        } else if(this->currentAvatarID == CHAR_ATM) {
            AtmInformation* atmInfo = this->gameModel->getAtmInformation();
            AtmBonus* atmBonus = (AtmBonus*) atmInfo->getBonusInfo()->getObjectAtIndex(this->currentBonusCard);
            nameText = (char*)"ATM";
            mpcText = (char*)this->gameModel->getCounter()->getTotalSpeed()->display();
            sprintf(upgradeNameText, "%s", atmBonus->getName().c_str());
            sprintf(upgradeEffectText, "%s", atmBonus->getEffect().c_str());
            sprintf(upgradeDescText, "%s", atmBonus->getDescription().c_str());
            requiredMoneyText = atmBonus->getMoneyRequired()->display();
            costUpgradeText = atmBonus->getPrice()->display();
        }
        //name
        char name[100];
        sprintf(name, "%s", nameText);
        this->nameLabel->setString(name);
        
        //mpc
        char mpc[100];
        if(this->currentAvatarID == CHAR_FINGER) {
            sprintf(mpc,"Money per click: $ %s", mpcText);
        } else if (this->currentAvatarID == CHAR_ATM) {
            sprintf(mpc,"Characters money per second: $ %s", mpcText);
        }
        delete[] mpcText;
        this->mpsLabel->setString(mpc);
        
        //upgrade name label
        char upgradeName[100];
        if(strcmp(currentStatus, "locked") == 0) {
            sprintf(upgradeName, "%s", "Locked Upgrade");
        } else {
            sprintf(upgradeName, "%s", upgradeNameText);
        }
        this->upgradeNameLabel->setString(upgradeName);
        
        //update effect label
        char upgradeEffect[100];
        if(strcmp(currentStatus, "locked") == 0) {
            sprintf(upgradeEffect, "%s", "\?\?\?-\?\?\?");
            this->upgradeEffectLabel->setPosition(490, 285);
        } else {
            sprintf(upgradeEffect, "%s", upgradeEffectText);
            this->upgradeEffectLabel->setPosition(490, 330);
        }
        this->upgradeEffectLabel->setString(upgradeEffect);
        
        //update required money
        if(strcmp(currentStatus, "locked") == 0) {
            char requiredMoney[100];
            if(this->currentAvatarID == CHAR_FINGER){
                sprintf(requiredMoney, "Required Touching Money: \n$ %s", requiredMoneyText);
            } else {
                sprintf(requiredMoney, "Required Total Get Money: \n$ %s", requiredMoneyText);
            }
            this->requiredMoneyLabel->setString(requiredMoney);
            this->requiredMoneyLabel->setVisible(true);
            delete[]requiredMoneyText;
        } else {
            this->requiredMoneyLabel->setVisible(false);
        }
        
        
        //upgrade desc label
        char upgradeDesc[100];
        sprintf(upgradeDesc, "%s", upgradeDescText);
        this->upgradeDescLabel->setString(upgradeDesc);
        
        if(strcmp(currentStatus, "locked") == 0) {
            this->upgradeDescLabel->setVisible(false);
        } else {
            this->upgradeDescLabel->setVisible(true);
        }
        
        //upgrade cost label
        char costUpgrade[100];
        sprintf(costUpgrade,TXT_MONEY_FORMAT, costUpgradeText);
        delete[]costUpgradeText;
        this->upgradeCostLabel->setString(costUpgrade);
        this->upgradeCostLabel->setPosition(818,175);
        
    }
}